package com.boc.ewr.uniapp.api.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.boc.ewr.bcimp.entity.BusAcctInfo;
import com.boc.ewr.bcimp.entity.Cac;
import com.boc.ewr.bcimp.service.IBusAcctInfoService;
import com.boc.ewr.bcimp.service.ICacService;
import com.boc.ewr.business.entity.AcctUncaDtl;
import com.boc.ewr.business.entity.ElmtbAssmtApply;
import com.boc.ewr.business.service.IAcctUncaDtlService;
import com.boc.ewr.business.service.IElmtbAssmtApplyService;
import com.boc.ewr.uniapp.api.vo.CaRateVo;
import com.boc.ewr.util.file.enumeration.ProcessStatusEnum;
import com.boc.ewr.util.file.enumeration.ProtocolTypeEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.SysDepartModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author : Wzz
 * @create : 2023-05- 24- 11:30
 * @desc :
 */
@Api(tags = "对账率")
@RestController
@RequestMapping("/uniapp/ca/rate")
@Slf4j
public class CaRateApiController {

    @Autowired
    private ISysBaseAPI sysBaseAPI;

    @Autowired
    private ICacService cacService;

    @Autowired
    private IAcctUncaDtlService acctUncaDtlService;

    @Autowired
    private IElmtbAssmtApplyService elmtbAssmtApplyService;

    @ApiOperation(value = "对账率-获取机构名称与对账率", notes = "对账率-获取机构名称与对账率")
    @GetMapping(value = "/getOrgNmCaRate")
    public Result<List<Map<String, CaRateVo>>> getOrgNmCaRate() {

        List<String> orgCodeList = new ArrayList<>();
        Set<String> orgCodeSetByLoginUser = sysBaseAPI.getOrgCodeSetByLoginUser(this.getLoginUser());
        if (orgCodeSetByLoginUser!=null) {
            orgCodeList = new ArrayList<>(orgCodeSetByLoginUser);
        }else {
            orgCodeList.add(this.getLoginUser().getOrgCode());
        }

        List<Map<String, CaRateVo>> maps = this.genOrgRate(orgCodeList);

        return Result.OK(maps);
    }

    // 生成Vo的List
    public List<Map<String, CaRateVo>> genOrgRate(List<String> orgCodeList) {
        List<Map<String, CaRateVo>> resultList = new ArrayList<>();
        for (String orgCode : orgCodeList) {
            Map<String, CaRateVo> resultMap = new HashMap<>();
            CaRateVo caRateVo = new CaRateVo();

            SysDepartModel sysDepartModel = sysBaseAPI.selectAllById(orgCode);
            caRateVo.setOrgNm(sysDepartModel.getDepartName());
            caRateVo.setOrgNo(orgCode);

            caRateVo.setRateName("非重点对账率");
            caRateVo.setRateData(this.calculateRate(orgCode, ProtocolTypeEnum.getNoFocusIndexSet()));
            resultMap.put("focusRate", caRateVo);
            caRateVo.setRateName("重点对账率");
            caRateVo.setRateData(this.calculateRate(orgCode, ProtocolTypeEnum.getFocusIndexSet()));
            resultMap.put("noFocusRate", caRateVo);
            resultList.add(resultMap);
        }
        return resultList;
    }

    // 计算单一网点的重点对账率
    public String calculateRate(String orgCode, Set<String> protocolTypeSet) {

        // 获取当前网点下的账户总数
        long countAllAcct = cacService.count(
                new LambdaQueryWrapper<Cac>()
                        .eq(Cac::getBranchNo, orgCode)
                        .in(Cac::getIskey, protocolTypeSet)
        );
        // 若当前网点下没有客户，则直接返回无客户
        if (countAllAcct == 0L) {
            return "暂无数据";
        }

        // 获取当前网点下未对账的账户数
        LambdaQueryWrapper<AcctUncaDtl> wrapper = new LambdaQueryWrapper<AcctUncaDtl>()
                .eq(AcctUncaDtl::getBranchNo, orgCode)
                .in(AcctUncaDtl::getProtocolType, protocolTypeSet);
        // todo 需要测试是否剔除
        if (ProtocolTypeEnum.getFocusIndexSet().equals(protocolTypeSet)) {
            // 重点账户要剔除考核
            Set<String> elmtbProtocolNoSet = elmtbAssmtApplyService.list(
                    new LambdaQueryWrapper<ElmtbAssmtApply>()
                            .eq(ElmtbAssmtApply::getOrgBranchNo, orgCode)
                            .eq(ElmtbAssmtApply::getCheckSta, ProcessStatusEnum.EFFECTIVE.getIndex())
            ).stream().map(ElmtbAssmtApply::getProtocolNo).collect(Collectors.toSet());
            wrapper.notIn(AcctUncaDtl::getProtocolNo, elmtbProtocolNoSet);
        }
        long countUnCaAcct = acctUncaDtlService.count(wrapper);

        BigDecimal result = new BigDecimal(1)
                .subtract(BigDecimal.valueOf(countUnCaAcct).divide(BigDecimal.valueOf(countAllAcct), 4, RoundingMode.HALF_UP))
                .multiply(BigDecimal.valueOf(100))
                .setScale(2, RoundingMode.HALF_UP);

        return result + "%";
    }


    private LoginUser getLoginUser() {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        return sysUser;
    }
}
